package com.yangtu.nearbyshop.db.service;

import com.github.pagehelper.PageHelper;
import com.yangtu.nearbyshop.db.dao.NearbyshopOrderMapper;
import com.yangtu.nearbyshop.db.dao.OrderMapper;
import com.yangtu.nearbyshop.db.domain.NearbyshopOrder;
import com.yangtu.nearbyshop.db.domain.NearbyshopOrderExample;
import com.yangtu.nearbyshop.db.util.OrderUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class NearbyshopOrderService {
    @Resource
    private NearbyshopOrderMapper nearbyshopOrderMapper;
    @Resource
    private OrderMapper orderMapper;

    public int add(NearbyshopOrder order) {
        order.setAddTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        return nearbyshopOrderMapper.insertSelective(order);
    }

    public int count(Integer userId) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return (int) nearbyshopOrderMapper.countByExample(example);
    }

    public int count(String mercNo) {
        List<Short> statusList= new ArrayList<>();
        statusList.add(OrderUtil.STATUS_PAY);
        statusList.add(OrderUtil.STATUS_SHIP);
       // statusList.add(OrderUtil.STATUS_CONFIRM);
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andMercNoEqualTo(mercNo).andOrderStatusIn(statusList)
                .andDeletedEqualTo(false);
        return (int) nearbyshopOrderMapper.countByExample(example);
    }

    public int countToday(String mercNo) {
        List<Short> statusList= new ArrayList<>();
        statusList.add(OrderUtil.STATUS_PAY);
        statusList.add(OrderUtil.STATUS_SHIP);
        statusList.add(OrderUtil.STATUS_CONFIRM);
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andMercNoEqualTo(mercNo).andAddTimeBetween(LocalDateTime.of(LocalDate.now(), LocalTime.MIN),LocalDateTime.of(LocalDate.now(), LocalTime.MAX)).andOrderStatusIn(statusList).andDeletedEqualTo(false);
        return (int) nearbyshopOrderMapper.countByExample(example);
    }

    public NearbyshopOrder findById(Integer orderId) {
        return nearbyshopOrderMapper.selectByPrimaryKey(orderId);
    }

    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public int countByOrderSn(Integer userId, String orderSn) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return (int) nearbyshopOrderMapper.countByExample(example);
    }

    // TODO 这里应该产生一个唯一的订单，但是实际上这里仍然存在两个订单相同的可能性
    public String generateOrderSn(Integer userId) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String now = df.format(LocalDate.now());
        String orderSn = now + getRandomNum(6);
        while (countByOrderSn(userId, orderSn) != 0) {
            orderSn = now +  getRandomNum(6);
        }
        return orderSn;
    }

    public List<NearbyshopOrder> queryByOrderStatus(Integer userId, List<Short> orderStatus, Integer page, Integer size) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.setOrderByClause(NearbyshopOrder.Column.addTime.desc());
        NearbyshopOrderExample.Criteria criteria = example.or();
        criteria.andUserIdEqualTo(userId);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        PageHelper.startPage(page, size);
        return nearbyshopOrderMapper.selectByExample(example);
    }

    public List<NearbyshopOrder> queryByOrderStatusMerc(String mercNo, List<Short> orderStatus, Integer page, Integer size) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.setOrderByClause(NearbyshopOrder.Column.addTime.desc());
        NearbyshopOrderExample.Criteria criteria = example.or();
        criteria.andMercNoEqualTo(mercNo);

        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        PageHelper.startPage(page, size);
        return nearbyshopOrderMapper.selectByExample(example);
    }
    public List<NearbyshopOrder> querySelective(Integer userId, String orderSn, List<Short> orderStatusArray,
                                                Integer page, Integer size, String sort, String order,
                                                String startTm,String endTm,String consignee,String mobile,String mercName) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        NearbyshopOrderExample.Criteria criteria = example.createCriteria();

        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        if (!StringUtils.isEmpty(orderSn)) {
            criteria.andOrderSnEqualTo(orderSn);
        }

        if (!StringUtils.isEmpty(consignee)) {
            criteria.andConsigneeEqualTo(consignee);
        }

        if (!StringUtils.isEmpty(mobile)) {
            criteria.andMobileEqualTo(mobile);
        }

        if (!StringUtils.isEmpty(mercName)) {
            criteria.andMercNameEaualTo(mercName);
        }

        if (orderStatusArray != null && orderStatusArray.size() != 0) {
            criteria.andOrderStatusIn(orderStatusArray);
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if(!StringUtils.isEmpty(startTm)){
            criteria.andAddTimeGreaterThanOrEqualTo(LocalDateTime.parse(startTm,df));
        }
        if(!StringUtils.isEmpty(endTm)){
            criteria.andAddTimeLessThan(LocalDateTime.parse(endTm,df));
        }

        criteria.andDeletedEqualTo(false);

        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        PageHelper.startPage(page, size);
        return nearbyshopOrderMapper.selectByExample(example);
    }

    public int updateWithOptimisticLocker(NearbyshopOrder order) {
        LocalDateTime preUpdateTime = order.getUpdateTime();
        order.setUpdateTime(LocalDateTime.now());
        return orderMapper.updateWithOptimisticLocker(preUpdateTime, order);
    }

    public void deleteById(Integer id) {
        nearbyshopOrderMapper.logicalDeleteByPrimaryKey(id);
    }

    public int count() {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andDeletedEqualTo(false);
        return (int) nearbyshopOrderMapper.countByExample(example);
    }

    public List<NearbyshopOrder> queryUnpaid() {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false);
        return nearbyshopOrderMapper.selectByExample(example);
    }

    public List<NearbyshopOrder> queryUnconfirm() {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_TAKEN)
                .andShipTimeIsNotNull().andDeletedEqualTo(false);
        return nearbyshopOrderMapper.selectByExample(example);
    }

    public NearbyshopOrder findBySn(String orderSn) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return nearbyshopOrderMapper.selectOneByExample(example);
    }

    public Map<Object, Object> orderInfo(Integer userId) {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        List<NearbyshopOrder> orders = nearbyshopOrderMapper.selectByExampleSelective(example, NearbyshopOrder.Column.orderStatus, NearbyshopOrder.Column.comments);

        int unpaid = 0;
        int unship = 0;
        int unrecv = 0;
        int uncomment = 0;
        for (NearbyshopOrder order : orders) {
            if (OrderUtil.isCreateStatus(order)) {
                unpaid++;
            } else if (OrderUtil.isPayStatus(order)) {
                unship++;
            } else if (OrderUtil.isShipStatus(order)) {
                unrecv++;
            } else if (OrderUtil.isConfirmStatus(order) || OrderUtil.isAutoConfirmStatus(order)) {
                uncomment += order.getComments();
            } else {
                // do nothing
            }
        }

        Map<Object, Object> orderInfo = new HashMap<Object, Object>();
        orderInfo.put("unpaid", unpaid);
        orderInfo.put("unship", unship);
        orderInfo.put("unrecv", unrecv);
        orderInfo.put("uncomment", uncomment);
        return orderInfo;

    }

    public List<NearbyshopOrder> queryComment() {
        NearbyshopOrderExample example = new NearbyshopOrderExample();
        example.or().andCommentsGreaterThan((short) 0).andDeletedEqualTo(false);
        return nearbyshopOrderMapper.selectByExample(example);
    }

    /**
     * 获取总分润
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @Date: 2019/4/25 19:58
    */
    public String getProfit(String mercNo) {

        return  nearbyshopOrderMapper.selectMercProfit(mercNo);
    }

    /**
     * 获取总销售额
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @Date: 2019/4/25 19:58
     */
    public String getTotalAmt(String mercNo) {

        return  nearbyshopOrderMapper.selectTotalAmt(mercNo);
    }

    /**
     * 获取某个时间段总分润
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @param startDt
     * @param endDt
     * @Date: 2019/4/25 19:58
     */
    public String getProfitByDt(String mercNo, String startDt, String endDt) {
        return  nearbyshopOrderMapper.selectMercProfitByDt(mercNo, startDt, endDt);
    }

    /**
     * 按照商品类型获取某个时间段总分润
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @param startDt
     * @param endDt
     * @Date: 2019/4/25 19:58
     */
    public List<Map<String, String>> getProfitByGoods(String mercNo, String startDt, String endDt, Integer page, Integer size) {

        PageHelper.startPage(page, size);
        return  nearbyshopOrderMapper.selectMercProfitByGoods(mercNo, startDt, endDt);

    }

    /**
     * 按照商户获取某个时间段商户总分润
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @param startDt
     * @param endDt
     * @Date: 2019/4/25 19:58
     */
    public List<Map<String, String>> getProfitByMerc(String mercNo, String startDt, String endDt, Integer page, Integer size) {

        PageHelper.startPage(page, size);
        return  nearbyshopOrderMapper.selectMercProfitByMerc(mercNo, startDt, endDt);

    }

    /**
     * 按照商户获取某个时间段商户推荐总分润
     * @author: ZhangJinChang
     * @Descripition:
     * @param mercNo
     * @param startDt
     * @param endDt
     * @Date: 2019/4/25 19:58
     */
    public List<Map<String, String>> getReferProfitByMerc(String mercNo, String startDt, String endDt) {

//        PageHelper.startPage(page, size);
        return  nearbyshopOrderMapper.selectMercReferProfitByMerc(mercNo, startDt, endDt);

    }

    public List<Map<String, Object>> selectOrderByCond(String mercNo, String orderStatus, String startTm,String endTm) {
        return  nearbyshopOrderMapper.selectOrderByCond(mercNo, orderStatus,startTm, endTm);

    }

    public void updateBatch(List<NearbyshopOrder> list){
        orderMapper.updateBatch(list);
    }
}
